/*
虽然java是面向对象的语言，但java不是纯面向对象的语言，比如基本数据类型就不是面向对象的。在学习泛型和集合之前，一定要学习基本类型的包装类。
基本类型，如果想通过对象的形式去使用他们，java提供的基本类型包装类，使得java能够更好的体现面向对象的思想，使得基本类型能够支持对象的操作。

char和布尔类型，直接继承Object类
char -> Character  字符串的基本类型，使用Character关键字转换为对象类型
boolean -> Boolean  基本的布尔类型，使用Boolean关键字转换为对象类型
数字类型的转换是继承Number类
byte -> Byte   基本类型的byte类型，要转换成对象，则使用Byte关键字
short -> Short  同上
int -> Integer
long -> Long
float -> Float
double -> Double

上面这些转换行为，叫包装类，实际是就是将我们的基本数据类型，封装成一个类，运用了封装的思想。
 */
package com.test.wrapperclass;

public class Main {
    public static void main(String[] args) {
        Integer i = 10;  //包装类型可以直接接收对应基本类型的数据，并变为一个对象，装箱操作
        System.out.println(i + 1);  //包装类型可以当做基本类型操作,拆箱操作
        //为什么包装类型能直接使用具体值来赋值呢，为什么包装类型能当做基本类型操作呢，用到了一个特性叫自动装箱和拆箱机制。
        //比如Integer i = 10; 反编译后是Integer i = Integer.valueOf(10);所以说本质上是通过Integer.valueOf帮我们生成一个Integer对象
        //但我用idea 反编译的结果不是这样？？？

        /*
        如果使用包装类进行运算，或是赋值给一个基本类型变量，包装类会进行自动拆箱
        */
        Integer a = Integer.valueOf(1);
        int b = a;  //简写
        int c = a.intValue();  //编译后的代码
        long d = a.longValue();  //还支持转换到其他类型
        double e = a.doubleValue();
        System.out.println(b);
        System.out.println(c);
        System.out.println(d);

        //包装类型对象之间的比较。包装类型能用==或equals比较么？
        Integer i1 = 456;
        Integer i2 = 456;
        System.out.println(i1==i2);  //使用双等号，比较是的两个对象是不是同一个对象（内存地址是否相同），因为不是同一个对象，返回false
        System.out.println(i1.equals(i2));  //使用equals，比较的是两个对象的值是否相等，返回true。可以点击equals查看对比的代码，对比的是intValue()，基本类型

        //如果是-128到127之间的数字呢？
        Integer i3 = 100;
        Integer i4 = 101;
        System.out.println(i3==i4);  //值不同，不是同一个对象
        System.out.println(i3.equals(i4));  //值不同

        //考虑下Integer cache缓存的影响
        Integer i5 = 100;
        System.out.println(i3==i5);  //返回true，因为范围在-128到127之间，缓存返回同一个对象，i3和i5实际为同一个对象，同一个内存地址。
        /*
        查看Integer 781行和829行，会发现定义了一个最小值-128和最大值127，判断i在不在这个范围内，在这个范围内才返回Integer对象
        还说这个值总是缓存-128到127之间的一个数值，如果我们定义了一个Integer对象在这个范围内，且缓存内已经有一个值相同的Integer对象了，
        就会把已缓存的对象定义一个新名字，而不是new一个新的对象。这里是个坑，面试高频考点。
        java为了优化，有一个缓存机制，如果是-128到127之间的数字，会直接使用已经缓存好的对象，而不是创建新的。
         */

        System.out.println(i3+2 == i4+1);  //返回true，因为做运算了，自动拆箱了，变成基本类型了。
    }
}






